home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 101-125 / disk_108 / tek / remote.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  10KB  |  392 lines

  1. /****************************************************
  2.  * vt100 emulator - remote character interpretation
  3.  *
  4.  *    v2.65       NG  - added tek4014 emulation
  5.  *    v2.6 870227 DBW - bug fixes for all the stuff in v2.5
  6.  *    v2.5 870214 DBW - more additions (see readme file)
  7.  *    v2.4 861214 DBW - lots of fixes/additions (see readme file)
  8.  *    v2.3 861101 DBW - minor bug fixes
  9.  *    v2.2 861012 DBW - more of the same
  10.  *    v2.1 860915 DBW - new features (see README)
  11.  *         860823 DBW - Integrated and rewrote lots of code
  12.  *    v2.0 860803 DRB - Rewrote the control sequence parser
  13.  *    v1.1 860720 DBW    - Switches, 80 cols, colors, bug fixes
  14.  *    v1.0 860712 DBW    - First version released
  15.  *
  16.  ****************************************************/
  17.  
  18. #include "vt100.h"
  19.  
  20. static int    p[10];
  21. static int    numpar;
  22. static char   escseq[40];
  23.  
  24. /************************************************
  25. *  function to handle remote characters
  26. *************************************************/
  27. void doremote(c)
  28. char c;
  29.     {
  30.     if (Tek(c))        /* added for tek emulation    */
  31.         return;
  32.  
  33.     if (c == 24) { inesc = 0; inctrl = 0; return; }
  34.     if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; }
  35.     if (inctrl >= 0 && c >= ' ') { doctrl(c); return; }
  36.     if (c == 10 || c == 11 || c == 12) {
  37.     if (nlmode) doindex('E'); else doindex('D');
  38.     return;
  39.     }
  40.     if (c == 13) {
  41.     if (!nlmode) emit(c);
  42.     return;
  43.     }
  44.     if (c == 15) { alt = 0; return; }
  45.     if (c == 14) { alt = 1; return; }
  46.     if (a[alt] && c > 94 && c < 127) { doalt(c); return; }
  47.     emit(c);
  48.     }
  49.  
  50. void doesc(c)
  51. char c;
  52. {
  53.     if (inesc < 0) { inesc = 0; return; }
  54.     if (c == 27 || c == 24) { inesc = -1; return; }
  55.     if (c < ' ' || c == 127) return;      /* Ignore control chars */
  56.  
  57.     /* Collect intermediates */
  58.     if (c < '0') {escseq[inesc++] = c; return; }
  59.  
  60.     /* by process of elimination, we have a final character.
  61.        Put it in the buffer, and dispatch on the first character
  62.        in the buffer */
  63.  
  64.     escseq[inesc] = c;
  65.     inesc = -1;                /* No longer collecting a sequence */
  66.     switch (escseq[0])            /* Dispatch on the first received */
  67.     {
  68.       case '[':                /* Control sequence introducer */
  69.     numpar = 0;            /* No parameters yet */
  70.     private = 0;            /* Not a private sequence (yet?) */
  71.     badseq = 0;            /* Good until proven bad */
  72.     p[0] = p[1] = 0;        /* But default the first parameter */
  73.     inctrl = 0;            /* We are in a control sequence */
  74.     return;                /* All done for now ... */
  75.  
  76.       case 'D': case 'E': case 'M':    /* Some kind of index */
  77.     doindex (c);            /* Do the index */
  78.     return;                /* Return */
  79.  
  80.       case '7':                /* Save cursor position */
  81.     savx = x; savy = y; savmode = curmode; savalt = alt;
  82.     sa[0] = a[0]; sa[1] = a[1];
  83.     return;
  84.  
  85.       case '8':                /* Restore cursor position */
  86.     x = savx; y = savy; alt = savalt; curmode = savmode;
  87.     a[0] = sa[0]; a[1] = sa[1];
  88.     return;
  89.  
  90.       case 'c':                /* Reset */
  91.     top = MINY; bot = MAXY; savx = MINX; savy = MINY;
  92.     curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0;
  93.     inesc = -1;
  94.     a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
  95.     redoutil();
  96.     emit(12);
  97.     return;
  98.  
  99.       case '(':                /* Change character set */
  100.     if (c == '0' || c == '2') a[0] = 1; else a[0] = 0;
  101.     return;
  102.  
  103.       case ')':                /* Change the other character set */
  104.     if (c == '0' || c == '2') a[1] = 1; else a[1] = 0;
  105.     return;
  106.  
  107.       case '=':                /* set keypad application mode */
  108.         p_keyapp = 1;
  109.     redoutil();
  110.         return;
  111.         
  112.       case '>':                /* reset application mode */
  113.         p_keyapp = 0;
  114.     redoutil();
  115.         return;
  116.         
  117.       case 'Z':
  118.     sendchar(27); sendstring("[?1;7c"); return;
  119.  
  120.       /* If we didn't match anything, we can just return, happy in the
  121.      knowledge that we've at least eaten the whole sequence */
  122.  
  123.     }                    /* End of switch */
  124.     return;
  125. }
  126.  
  127. void doctrl(c)
  128. char c;
  129. {
  130.     int        i;
  131.  
  132.     if (c == 27 || c == 24) { inctrl = -1; return; }
  133.     if (c < ' ' || c == 127) return;          /* Ignore control chars */
  134.  
  135.     /* First, look for some parameter characters.  If the very first
  136.     parameter character isn't a digit, then we have a 
  137.     private sequence */
  138.  
  139.     if (c >= '0' && c < '@')
  140.     {
  141.     /* can't have parameters after intermediates */
  142.     if (inctrl > 0) {badseq++ ; return; }
  143.     switch (c)
  144.     {
  145.       case '0': case '1': case '2': case '3': case '4':
  146.       case '5': case '6': case '7': case '8': case '9':
  147.         p[numpar] = p[numpar] * 10 + (c - '0');
  148.         return;
  149.  
  150.       case ';':
  151.         p[++numpar] = 0;        /* Start a new parameter */
  152.         return;
  153.  
  154.       case '<': case '=': case '>': case '?': /* Can only mean private */
  155.  
  156.         /* Only allowed BEFORE parameters */
  157.             if (inctrl == 0) private = c;
  158.         return;
  159.  
  160.     /* if we come here, it's a bad sequence */
  161.     }
  162.     badseq++;            /* Flag the bad sequence */
  163.     }
  164.  
  165.     if (c < '0')            /* Intermediate character */
  166.     {
  167.     escseq[inctrl++] = c;        /* Save the intermediate character */
  168.     return;
  169.     }
  170.  
  171.     /* if we get here, we have the final character.  Put it in the 
  172.        escape sequence buffer, then dispatch the control sequence */
  173.  
  174.     numpar++;                /* Reflect the real number of parameters */
  175.     escseq[inctrl++] = c;        /* Store the final character */
  176.     escseq[inctrl] = '\000';        /* Tie off the buffer */
  177.     inctrl = -1;            /* End of the control sequence scan */
  178.  
  179.     /* Don't know how to do most private sequences right now,
  180.     so just punt them */
  181.  
  182.     if ((private != 0 && private != '?') || badseq != 0) return;
  183.     if (private == '?' && escseq[0] != 'h' &&
  184.     escseq[0] != 'l') return;
  185.  
  186.     switch (escseq[0])            /* Dispatch on first intermediate or final */
  187.     {
  188.       case 'A': if (p[0]<=0) p[0] = 1;
  189.         y -= 8*p[0]; if (y<top)  y = top;  return;
  190.       case 'B': if (p[0]<=0) p[0] = 1;
  191.         y += 8*p[0]; if (y>bot)  y = bot;  return;
  192.       case 'C': if (p[0]<=0) p[0] = 1;
  193.         x += 8*p[0]; if (x>MAXX) x = MAXX; return;
  194.       case 'D': if (p[0]<=0) p[0] = 1;  
  195.         x -= 8*p[0]; if (x<MINX) x = MINX; return;
  196.  
  197.       case 'H': case 'f':        /* Cursor position */
  198.     if (p[0] <= 0) p[0] = 1;
  199.     if (p[1] <= 0) p[1] = 1;
  200.     y = (--p[0]*8)+MINY; x = (--p[1]*8)+MINX;
  201.     if (y > MAXY) y = MAXY;
  202.     if (x > MAXX) x = MAXX;
  203.     if (y < MINY) y = MINY;
  204.     if (x < MINX) x = MINX;
  205.     return;
  206.  
  207.       case 'L':                /* ANSI insert line */
  208.       case 'M':                /* ANSI delete line */
  209.     if (p[0] <= 0) p[0] = 1;
  210.     ScrollRaster(mywindow->RPort,0L,
  211.         (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]),
  212.         (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1);
  213.     return;
  214.  
  215.       case 'r':                /* Set scroll region */
  216.     if (p[0] <= 0) p[0] = 1;
  217.     if (p[1] <= 0) p[1] = p_lines;
  218.     top = (--p[0]*8)+MINY; bot = (--p[1]*8)+MINY;
  219.     if (top < MINY) top = MINY;
  220.     if (bot > MAXY) bot = MAXY;
  221.     if (top > bot) { top = MINY; bot = MAXY; }
  222.     x = MINX; y = MINY;
  223.     return;
  224.  
  225.       case 'm':                /* Set graphic rendition */
  226.     for (i=0;i<numpar;i++) {
  227.         if (p[i] < 0) p[i] = 0;
  228.         switch (p[i]) {
  229.         case 0:
  230.         curmode  = FS_NORMAL;
  231.         break;
  232.  
  233.         case 1:
  234.         curmode |= FSF_BOLD;
  235.         break;
  236.  
  237.         case 4:
  238.         curmode |= FSF_UNDERLINED;
  239.         break;
  240.  
  241.         case 5:
  242.         curmode |= FSF_ITALIC;
  243.         break;
  244.  
  245.         default:
  246.         curmode |= FSF_REVERSE;
  247.         break;
  248.         }
  249.         }
  250.     return;
  251.  
  252.       case 'K':                /* Erase in line */
  253.     doerase();
  254.     return;
  255.  
  256.       case 'J':                /* Erase in display */
  257.     if (p[0] < 0) p[0] = 0;
  258.     SetAPen(mywindow->RPort,0L);
  259.     if (p[0] == 0) {
  260.         if (y < MAXY) RectFill(mywindow->RPort,
  261.         (long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1));
  262.         }
  263.     else if (p[0] == 1) {
  264.         if (y > MINY) RectFill(mywindow->RPort,
  265.         (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7));
  266.         }
  267.     else RectFill(mywindow->RPort,
  268.         (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
  269.     SetAPen(mywindow->RPort,1L);
  270.     doerase(); return;
  271.  
  272.       case 'h':                /* Set parameter */
  273.     if (private == 0 && p[0] == 20)        nlmode = 1;
  274.     else if (private == '?') {
  275.         if      (p[0] == 7)    p_wrap   = 1;
  276.         else if (p[0] == 1)    p_curapp = 1;
  277.         redoutil();
  278.         }
  279.     return;
  280.  
  281.       case 'l':                /* Reset parameter */
  282.     if (private == 0 && p[0] == 20)        nlmode = 0;
  283.     else if (private == '?') {
  284.         if      (p[0] == 7)    p_wrap   = 0;
  285.         else if (p[0] == 1) p_curapp = 0;
  286.         redoutil();
  287.         }
  288.     return;
  289.  
  290.       case 'x':
  291.     sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return;
  292.  
  293.       case 'n':
  294.     if (p[0] == 6) {
  295.         sendchar(27);
  296.         sprintf(escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
  297.         sendstring(escseq); return;
  298.         }
  299.     sendchar(27); sendstring("[0n"); return;
  300.  
  301.       case 'c':
  302.     sendchar(27); sendstring("[?1;7c"); return;
  303.     }
  304.  
  305.     /* Don't know how to do this one, so punt it */
  306. }
  307.  
  308. void doindex(c)
  309. char c;
  310.     {
  311.     if (c != 'M') {
  312.     if (c == 'E') x = MINX;
  313.     if (y > bot) if (y < MAXY) y += 8;
  314.     if (y == bot)
  315.         ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,(long)(top-6),
  316.         (long)(MAXX+7),(long)(bot+1));
  317.     if (y < bot) y += 8;
  318.     }
  319.     else {
  320.     if (y < top) if (y > MINY) y -= 8;
  321.     if (y == top)
  322.         ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6),
  323.         (long)(MAXX+7),(long)(bot+1));
  324.     if (y > top) y -= 8;
  325.     }
  326.     return;
  327.     }
  328.  
  329. doalt(c)
  330. char c;
  331.     {
  332.     int oldx,newx;
  333.     inesc = -1;
  334.     oldx = x; emit(' '); newx = x;
  335.     x = oldx;
  336.     SetAPen(mywindow->RPort,1L);
  337.     switch (c) {
  338.     case 'a':
  339.     doline(0,-6,8,1);
  340.     break;
  341.  
  342.     case 'j':
  343.     case 'm':
  344.     case 'v':   doline(4,-6,4,-2);
  345.     if      (c=='j')  doline(0,-2,4,-2);
  346.     else if (c=='m')  doline(4,-2,8,-2);
  347.     else              doline(0,-2,8,-2);
  348.     break;
  349.  
  350.     case 'k':
  351.     case 'l':
  352.     case 'w': doline(4,-2,4,1);
  353.     if      (c=='k')  doline(0,-2,4,-2);
  354.     else if (c=='l')  doline(4,-2,8,-2);
  355.     else              doline(0,-2,8,-2);
  356.     break;
  357.  
  358.     case 'n':
  359.     case 'q': doline(0,-2,8,-2);
  360.     if      (c=='n')  doline(4,-6,4,2);
  361.     break;
  362.  
  363.     case 't':
  364.     case 'u':
  365.     case 'x':   doline(4,-6,4,1);
  366.     if      (c=='t')  doline(4,-2,8,-2);
  367.     else if (c=='u')  doline(0,-2,4,-2);
  368.     break;
  369.     }
  370.     x = newx;
  371.     }
  372.  
  373. doline(x1,y1,x2,y2) {
  374.     RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1),
  375.     (long)(x+x2),(long)(y+y2));
  376.     }
  377.  
  378. void doerase()
  379.     {
  380.     if (p[0] < 0) p[0] = 0;
  381.     SetAPen(mywindow->RPort,0L);
  382.     if (p[0] == 0) RectFill(mywindow->RPort,(long)x,(long)(y-6),
  383.     (long)(MAXX+7),(long)(y+1));
  384.     else if (p[0] == 1) RectFill(mywindow->RPort,
  385.     (long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
  386.     else RectFill(mywindow->RPort,
  387.     (long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
  388.     SetAPen(mywindow->RPort,1L);
  389.     return;
  390.     }
  391.  
  392.